package com.zzyl.serve.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import cn.hutool.Hutool;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.bean.BeanUtils;
import com.zzyl.serve.domain.*;
import com.zzyl.serve.dto.CheckInApplyDto;
import com.zzyl.serve.dto.ElderFamilyDto;
import com.zzyl.serve.mapper.*;
import com.zzyl.serve.util.CodeGenerator;
import com.zzyl.serve.vo.CheckInConfigVo;
import com.zzyl.serve.vo.CheckInDetailVo;
import com.zzyl.serve.vo.CheckInElderVo;
import com.zzyl.serve.vo.ElderFamilyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import com.zzyl.serve.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

/**
 * 入住Service业务层处理
 *
 * @author wangyc
 * @date 2025-08-15
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private CheckInConfigMapper checkInConfigMapper;

    /**
     * 查询入住
     *
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return checkInMapper.selectById(id);
    }

    /**
     * 查询入住列表
     *
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return checkInMapper.insert(checkIn);
    }

    /**
     * 修改入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return checkInMapper.updateById(checkIn);
    }

    /**
     * 批量删除入住
     *
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return checkInMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除入住信息
     *
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return checkInMapper.deleteById(id);
    }

    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private BedMapper bedMapper;


    @Autowired
    private ContractMapper contractMapper;



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void apply(CheckInApplyDto checkInApplyDto) {

        LambdaQueryWrapper<Elder> wrapper = Wrappers.<Elder>lambdaQuery()
                .eq(Elder::getIdCardNo, checkInApplyDto.getCheckInElderDto().getIdCardNo());

        Elder elder = elderMapper.selectOne(wrapper);
        //1.判断老人是否入住
        if (elder != null && Objects.equals(elder.getStatus(), 1)) {
            throw new BaseException("老人已入住，不能再次申请");
        }

        //2.更新床位状态为已入住
        //2.1判断床位是否已入住
        Bed bed = bedMapper.selectBedById(checkInApplyDto.getCheckInConfigDto().getBedId());
        if (Objects.equals(bed.getBedStatus(), 1)) {
            throw new BaseException("床位已入住");
        } else {
            //2.2更新床位状态
            bed.setBedStatus(1);
            bedMapper.updateBed(bed);
        }
        //3.新增或者更新老人
        //3.1更新老人
        Elder newElder = new Elder();
        BeanUtils.copyProperties(checkInApplyDto.getCheckInElderDto(),newElder);
        newElder.setStatus(1);
        newElder.setBedNumber(bed.getBedNumber());
        newElder.setBedId(bed.getId());
       //获取家属列表
        List<ElderFamilyDto> familyDtoList = checkInApplyDto.getElderFamilyDtoList();
        //转字符串
        String jsonStr = JSONUtil.toJsonStr(familyDtoList);
        newElder.setRemark(jsonStr);

        if (elder != null) {
            newElder.setId(elder.getId());
            elderMapper.updateById(newElder);
        } else {
            //3.2新增老人
            elderMapper.insert(newElder);
        }
        //4.新增入住信息
        CheckIn checkIn =new CheckIn();
        checkIn.setElderName(newElder.getName());
        checkIn.setElderId(newElder.getId());
        checkIn.setIdCardNo(newElder.getIdCardNo());
        checkIn.setStartDate(checkInApplyDto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(checkInApplyDto.getCheckInConfigDto().getEndDate());
        checkIn.setNursingLevelName(checkInApplyDto.getCheckInConfigDto().getNursingLevelName());
        checkIn.setBedNumber(bed.getBedNumber());
        checkIn.setStatus(0);
        save(checkIn);


        //5.新增入住配置
        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyProperties(checkInApplyDto.getCheckInConfigDto(),checkInConfig);
        checkInConfig.setCheckInId(checkIn.getId());
        checkInConfigMapper.insert(checkInConfig);

        //6.新增签约办理
        Contract contract = new Contract();
        contract.setElderId(newElder.getId());
        BeanUtils.copyProperties(checkInApplyDto.getCheckInContractDto(),contract);
        contract.setElderName(newElder.getName());
        contract.setStartDate(checkInApplyDto.getCheckInConfigDto().getStartDate());
        contract.setEndDate(checkInApplyDto.getCheckInConfigDto().getEndDate());
        Boolean isOutDate = LocalDateTime.now().isAfter(contract.getEndDate())||LocalDateTime.now().isBefore(contract.getStartDate());
        contract.setStatus(isOutDate?0:1);
         contract.setContractNumber( CodeGenerator.generateContractNumber());
        contractMapper.insert(contract);


    }

    @Override
    public CheckInDetailVo detailById(Long id) {
        CheckIn checkIn = getById(id);

        CheckInElderVo checkInElderVo = new CheckInElderVo();
        //1.查询老人信息
        //先获取老人表主键id
        Elder elder = elderMapper.selectElderById(checkIn.getElderId());
        BeanUtils.copyProperties(elder,checkInElderVo);
        //计算年龄 132123196712131239  7-14
        String idCardNo = elder.getIdCardNo();
        String birthdayString = idCardNo.substring(6, 14);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate birthday = LocalDate.parse(birthdayString, formatter);
        int age =  Period.between(birthday, LocalDate.now()).getYears();
        checkInElderVo.setAge(age);

        //2.查询家属信息
        //elder中的getRemark字段的数据转换为数组
        String remark = elder.getRemark();
        if (remark == null) {
            throw  new BaseException("信息不完善");
        }
        List<ElderFamilyVo> familyDtoList = JSONUtil.toList(remark, ElderFamilyVo.class);

        //3.查询入职配置信息
        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
        //使用Wrappers中的LambdaQuery的条件查询
        LambdaQueryWrapper<CheckInConfig> checkId = Wrappers.<CheckInConfig>lambdaQuery().eq(CheckInConfig::getCheckInId, id);
        CheckInConfig checkInConfig = checkInConfigMapper.selectOne(checkId);
        if (checkInConfig == null) {
            throw  new BaseException("信息不完善");
        }
        BeanUtils.copyProperties(checkInConfig,checkInConfigVo);
        //设置开始日期和结束日期以及床号从入住表中获取
        checkInConfigVo.setStartDate(checkIn.getStartDate());
        checkInConfigVo.setEndDate(checkIn.getEndDate());
        checkInConfigVo.setBedNumber(checkIn.getBedNumber());

        //4.查询合同信息
        //使用Wrappers中的LambdaQuery的条件查询
        LambdaQueryWrapper<Contract> elderId = Wrappers.<Contract>lambdaQuery().eq(Contract::getElderId, elder.getId());

        Contract contract = contractMapper.selectOne(elderId);
        if (contract == null) {
            throw  new BaseException("信息不完善");
        }
        CheckInDetailVo checkInDetailVo = new CheckInDetailVo();
        checkInDetailVo.setCheckInElderVo(checkInElderVo);
        checkInDetailVo.setElderFamilyVoList(familyDtoList);
        checkInDetailVo.setCheckInConfigVo(checkInConfigVo);
        checkInDetailVo.setContract(contract);

        return checkInDetailVo;
    }
}
